package com.example.dessertstoressm.Service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.dessertstoressm.Mapper.OrderMapper;
import com.example.dessertstoressm.Mapper.OrderStatusMapper;
import com.example.dessertstoressm.Service.ItemService;
import com.example.dessertstoressm.Service.LineItemService;
import com.example.dessertstoressm.Service.OrderService;
import com.example.dessertstoressm.Service.SequenceService;
import com.example.dessertstoressm.domain.*;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl implements OrderService {
    @Resource
    private OrderMapper orderMapper;
    @Resource
    private OrderStatusMapper orderStatusMapper;
    @Resource
    private SequenceService sequenceService;
    @Resource
    private ItemService itemService;
    @Resource
    private LineItemService lineItemService;

    @Override
    public List<Order> getOrdersByUsername(String username){
        QueryWrapper<Order> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("userid",username);
        wrapper1.orderByAsc("orderdate");
        List<Order> orders = this.orderMapper.selectList(wrapper1);
        for(Order order : orders){
            QueryWrapper<OrderStatus> wrapper2 = new QueryWrapper<>();
            wrapper2.eq("orderid",order.getOrderId());
            order.setStatus(this.orderStatusMapper.selectOne(wrapper2).getStatus());
        }
        return orders;
    }

    @Override
    public Order getOrder(int orderId){
        QueryWrapper<Order> wrapper1 = new QueryWrapper<>();
        wrapper1.eq("orderid",orderId);
        Order order = this.orderMapper.selectOne(wrapper1);
        QueryWrapper<OrderStatus> wrapper2 = new QueryWrapper<>();
        wrapper2.eq("orderid",orderId);
        order.setStatus(this.orderStatusMapper.selectOne(wrapper2).getStatus());

        order.setLineItems(lineItemService.getLineItemsByOrderId(orderId));
        for (int i = 0; i < order.getLineItems().size(); i++) {
            LineItem lineItem = order.getLineItems().get(i);
            Item item = itemService.getItem(lineItem.getItemId());
            item.setQuantity(itemService.getInventoryQuantity(lineItem.getItemId()));
            lineItem.setItem(item);
        }

        return order;
    }

    @Override
    public void insertOrder(Order order){
        order.setOrderId(getNextId("ordernum"));

        for (int i = 0; i < order.getLineItems().size(); i++) {
            LineItem lineItem = order.getLineItems().get(i);
            String itemId = lineItem.getItemId();
            Integer increment = lineItem.getQuantity();
            Map<String, Integer> param = new HashMap<>();
            param.put(itemId, increment);
            itemService.updateInventoryQuantity(param);
        }

        this.orderMapper.insert(order);
        insertOrderStatus(order);

        for (int i = 0; i < order.getLineItems().size(); i++) {
            LineItem lineItem = order.getLineItems().get(i);
            lineItem.setOrderId(order.getOrderId());
            lineItemService.insertLineItem(lineItem);
        }

    }

    @Override
    public void insertOrderStatus(Order order){
        OrderStatus orderStatus = new OrderStatus(order.getOrderId(), order.getOrderId(), order.getOrderDate(),order.getStatus());
        this.orderStatusMapper.insert(orderStatus);
    }

    @Override
    public int getNextId(String name) {
        Sequence sequence = new Sequence(name, -1);
        sequence = sequenceService.getSequence(sequence);
        if (sequence == null) {
            throw new RuntimeException("Order Error: A null sequence was returned from the database (could not get next " + name
                    + " sequence).");
        }
        Sequence parameterObject = new Sequence(name, sequence.getNextId() + 1);
        sequenceService.updateSequence(parameterObject);
        return sequence.getNextId();
    }

    @Override
    public void updateOrderPayStatus(Order order){
        QueryWrapper<Order> wrapper = new QueryWrapper<>();
        wrapper.eq("paystatus", order.getPayStatus());
        this.orderMapper.update(order,wrapper);
    }

}
